/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.pdx.cs.guavadata;

import edu.pdx.cs.guavadata.data.Scheme;
import edu.pdx.cs.guavadata.condition.Condition;
import edu.pdx.cs.guavadata.query.Command;
import edu.pdx.cs.guavadata.query.Operator;
import edu.pdx.cs.guavadata.subclass.ControlType;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

/**
 *
 * @author VuTran
 */
public class GQueryNode extends DefaultMutableTreeNode {
    
    List<GQueryNode> semanticAdditions;
    public boolean print;
    boolean isValue;
    public GTree g;
    String matchedProp;
    boolean found;
    public Condition gqCondition;
    JTree tree;
    
    // Transient flags for query processing
    boolean inQuery;
    
    GQueryNode(GTree gin) {
        this();
        this.g = gin;
        if (g.getCType() == ControlType.Attribute)
            isValue = true;
        else
            isValue = false;
        setUserObject(gin.getGName());
    }

    public GQueryNode() {
        print = false;
        found = false;
        inQuery = false;
        matchedProp = null;
        gqCondition = null;
        semanticAdditions = new ArrayList<GQueryNode>();

    }

    // tranverse the tree to get all the nodes from root to current node
    @Override
    public String toString() {
        String sTemp;
        GTree gTemp;

        sTemp = g.getGName();
        gTemp = g.parent;

        while (gTemp != null) {
            sTemp = gTemp.getGName() + "/" + sTemp;
            gTemp = gTemp.parent;
        }

        return sTemp;
    }

    public boolean getIsValue() {
        return this.isValue;
    }

    /*
     * Tranverse the whole tree to find the "value".
     * Condition can be "EQUALS" or "CONTAINS".
     * The property that has the value will be recorded in this.matchedProp
     */
    public void traverseNFindNodes(JTree trv, String value, String condition) {
        TreeModel tm = trv.getModel();
        GQueryNode root = (GQueryNode) tm.getRoot();
        for (int i = 0; i < root.getChildCount(); i++) {
            GQueryNode temp = (GQueryNode) root.getChildAt(i);
            temp.setAttributeRec(value, condition);
        }
    }

    private void setAttributeRec(String sparam, String scond) {
        this.setAttributes(sparam, scond);
        for (int i = 0; i < this.getChildCount(); i++) {
            GQueryNode temp = (GQueryNode) this.getChildAt(i);
            temp.setAttributeRec(sparam, scond);
        }
    }

    private void setAttributes(String srchText, String srchCond) {
        this.matchedProp = null;
        this.found = false;

        if (srchCond.equals("EQUAL TO")) {
            if (this.g.getGName() != null) {
                if (srchText.toLowerCase().equals(this.g.getGName().toLowerCase())) {
                    this.matchedProp += " : " + "Name";
                    this.found = true;
                }
            }

            if (this.g.getGText() != null) {
                if (srchText.toLowerCase().equals(this.g.getGText().toLowerCase())) {
                    this.matchedProp += " : " + "Text";
                    this.found = true;
                }
            }
            if ((this.g.getGDomain() != null) && (this.g.getGDomain().getDBType() != null)) {
                if (srchText.toLowerCase().equals(this.g.getGDomain().getDBType().toLowerCase())) {
                    this.matchedProp += " : " + "Domain.DBType";
                    this.found = true;
                }
            }
            if (this.g.getGToolTip() != null) {
                if (srchText.toLowerCase().equals(this.g.getGToolTip().toLowerCase())) {
                    this.matchedProp += " : " + "ToolTip";
                    this.found = true;
                }
            }
            if (this.g.getGDefault() != null) {
                if (srchText.toLowerCase().equals(this.g.getGDefault().toLowerCase())) {
                    this.matchedProp += " : " + "Default";
                    this.found = true;
                }
            }
        } else {
            if (srchCond.equals("CONTAINS")) {
                if (this.g.getGName() != null) {
                    if (this.g.getGName().toLowerCase().contains(srchText.toLowerCase())) {
                        this.matchedProp += " : " + "Name";
                        this.found = true;
                    }
                }
                if (this.g.getGText() != null) {
                    if (this.g.getGText().toLowerCase().contains(srchText.toLowerCase())) {
                        this.matchedProp += " : " + "Text";
                        this.found = true;
                    }
                }
                if ((this.g.getGDomain() != null) && (this.g.getGDomain().getDBType() != null)) {
                    if (this.g.getGDomain().getDBType().toString().toLowerCase().contains(srchText.toLowerCase())) {
                        this.matchedProp += " : " + "Domain.DBType";
                        this.found = true;
                    }
                }
                if (this.g.getGToolTip() != null) {
                    if (this.g.getGToolTip().toLowerCase().contains(srchText.toLowerCase())) {
                        this.matchedProp += " : " + "ToolTip";
                        this.found = true;
                    }
                }
                if (this.g.getGDefault() != null) {
                    if (this.g.getGDefault().toLowerCase().contains(srchText.toLowerCase())) {
                        this.matchedProp += " : " + "Default";
                        this.found = true;
                    }
                }
            }
        }//else
    }

    public void traverseNSetNodes(JTree trv, Character mode) {
        TreeModel tm = trv.getModel();
        GQueryNode root = (GQueryNode) tm.getRoot();
        for (int i = 0; i < root.getChildCount(); i++) {
            GQueryNode temp = (GQueryNode) root.getChildAt(i);
            temp.setNodesAppearance(mode, trv);
        }
    }

    public void setNodesAppearance(char mode, JTree trv) {
        this.setNode(mode, trv);
        for (int i = 0; i < this.getChildCount(); i++) {
            GQueryNode temp = (GQueryNode) this.getChildAt(i);
            temp.setNodesAppearance(mode, trv);
        }
    }

    public void setNode(char mode, JTree trv) {
        List<String> nodesInPath = new ArrayList<String>();
        if (mode == 'C') {
            //this.BackColor = Color.White
            if (this.g.getCType() == ControlType.Container || this.g.getCType() == ControlType.None)
                this.setUserObject("(" + g.getGName() + ")");
            else
                this.setUserObject(g.getGName());
            trv.collapsePath(new TreePath(this.getUserObjectPath()));
        } else if ((mode == 'S') && (this.found)) {
            // new yet implement
        }
    }

    private void traverseNExpand(List<String> nodes, JTree trv) {
        // not yet implement
    }

    private void expandChildNodes(List<String> nodes) {
        // not yet implement
    }

    private void expandNode(List<String> fullPath) {
        // not yet implement
    }

    public void resetJTree(JTree trv) {
        TreeModel tm = trv.getModel();
        GQueryNode root = (GQueryNode) tm.getRoot();
        for (int i = 0; i < root.getChildCount(); i++) {
            GQueryNode temp = (GQueryNode) root.getChildAt(i);
            temp.resetChildNodes();
        }
    }

    public void resetChildNodes() {
        this.print = false;
        this.found = false;
        this.matchedProp = null;
        this.gqCondition = null;
        //this.BackColor = Color.While;
        this.setUserObject(this.g.getGName());
        //this.collapse();
        //this.checked = false;
        for (int i = 0; i < this.getChildCount(); i++) {
            GQueryNode temp = (GQueryNode) this.getChildAt(i);
            temp.resetChildNodes();
        }
    }
    
    // this function query part of the tree
    public Scheme toQueryOutputScheme() {

        GQueryNode root = (GQueryNode) this.getRoot();
        Scheme s = new Scheme("Query", null);

        for (int i = 0; i < root.getChildCount(); i++) {
            GQueryNode temp = (GQueryNode) root.getChildAt(i);
            temp.visitToQueryOutputScheme(s);
        }

        return s;
    }

    private void visitToQueryOutputScheme(Scheme s) {
        // allow query part of the tree, not implemented yet
    }

    public static Command toQuery(JTree trv) {
        return null;
    }

    public GQueryNode pruneQueryMarks() {
        return null;
    }

    private void markQueryNodes() {

    }
}
